<template>
  <el-upload
    ref="uploadFile"
    class="upload-demo"
    :auto-upload="false"
    :limit="1"
    :on-change="handleFileChange"
    :on-exceed="handleExceed"
  >
    <template #trigger>
      <el-button type="primary">选择文件</el-button>
    </template>
    <template #tip>
      <div class="el-upload__tip">{{ tip }}</div>
    </template>
  </el-upload>
</template>
<script lang="ts" setup>
/*
 * 文件上传组件
 */
// import TreeSelect from '@/components/TreeSelect.vue';
import { ref, onMounted, watch } from 'vue';
import Request from '@/api/request/request';
import type { TreeData, TreeProps } from '@/types/interface/base_interface';
import { genFileId, type UploadInstance, type UploadProps, type UploadRawFile } from 'element-plus';
// 获取父组件传递过来的值，主要用于部门模块
// const table = inject<TableData>('table'); // 表格信息
// 获取父组件传递过来的值
interface Props {
  tip?: string; //服务端接口地址。和data一般是二选一，即如果是父组件已经传入了data则不不在从服务端读取数据
}
const props = withDefaults(defineProps<Props>(), {
  tip: '上传文件不超过5M'
});
//在v-model绑定的值。将选中的文件信息绑定表单对象
const fileModel = defineModel<File>({
  required: false,
  default: undefined
});
//定义上传组件对象
const uploadFile = ref<UploadInstance>();
// 当文件列表改变时
const handleFileChange: UploadProps['onChange'] = (uploadFile, uploadFiles) => {
  fileModel.value = uploadFile.raw!;
};
//当文件超出限制时，会用当前文件替换之前的文件。代码来源于element plus官方范例
const handleExceed: UploadProps['onExceed'] = (files) => {
  //清空之前的文件信息
  uploadFile.value!.clearFiles();
  //获取本次上传的文件对象
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  //让文件上传组件中的文件为新的文件。此时会触发文件列表改动函数handleFileChange
  uploadFile.value!.handleStart(file);
};
// 注意，监听对象中的属性，只能用这种watch的写法。不能使用写法：watch(props.query.createTimeQueryOfBegin,(newVal:string,oldVal:string)=>{});
watch(
  () => fileModel.value,
  (newVal: File | undefined, oldVal: File | undefined) => {
    //如果原来有文件，新的值没有了文件，则说明这个文件变量在组件外被清空
    if (typeof newVal === 'undefined' && typeof oldVal !== 'undefined') {
      //清空文件列表
      uploadFile.value!.clearFiles();
    }
  },
  { deep: true, immediate: true }
);
</script>
<style scoped></style>
